package com.qin.config;

import com.qin.properties.LogProperties;
import com.qin.service.LogService;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.RetryNTimes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

/**
 * 定义一个自动配置类。满足条件的Bean将会被实例化到Spring容器中去
 *
 * 说明：
 *  1. EnableConfigurationProperties：该注解是用来开启对ConfigurationProperties 注解配置Bean的支持。也就是
 *     EnableConfigurationProperties注解告诉Spring Boot 能支持@ConfigurationProperties；
 *  2. ConditionalOnProperty 注解控制Configuration 是否生效。简单来说也就是我们可以通过在yml配置文件中控制Configuration
 *     注解的配置类是否生效。例如，本例中只有 qin.log.open = true 时这个配置类才会生效
 *
 * @author qinxh
 * @date 2020/08/12
 */
@Configuration
@EnableConfigurationProperties(LogProperties.class)
@ConditionalOnProperty(
                prefix = "qin.log",
                name = "open",
                havingValue = "true"
)
public class LogConfig {

    @Autowired
    private LogProperties logProperties;

    private static CuratorFramework client = null;

    private static RetryPolicy retryPolicy = null;

    private static LogProperties properties = null;

    /**
     * 初始化zk客户端
     */
    @PostConstruct
    public void init (){

        properties = logProperties;

        // 使用重试策略创建Zk客户端
        retryPolicy = new RetryNTimes(logProperties.getZkTryTimes(), logProperties.getZkBetweenRetries());
        client = CuratorFrameworkFactory.builder()
                .connectString(logProperties.getZkPath())
                .sessionTimeoutMs(logProperties.getZkSessionTimeout())
                .connectionTimeoutMs(logProperties.getZkConnTimeout())
                .retryPolicy(retryPolicy)
                //指定命名空间后，client 的所有路径操作都会以/workspace 开头
                .namespace(logProperties.getZkLogWorkspace()).build();

        //开启连接
        client.start();
        System.out.println("zookeeper连接完成...");
    }

    public static CuratorFramework getClient() {

        return client ;
    }

    public static RetryPolicy getRetryPolicy() {

        return retryPolicy;
    }

    public static LogProperties getLogProperties() {

        return properties;
    }

    /**
     * 将LogService类定义为一个Bean，交给Ioc容器
     *
     * 说明：
     *  ConditionalOnMissingBean(AnimalService.class)注解表示容器中没有LogService这个Bean的时候才注入这个Bean
     */
    @Bean
    @ConditionalOnMissingBean(LogService.class)
    public LogService animalService() throws Exception {

        return new LogService();
    }
}
